package ru.compft.common.dao.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import ru.compft.common.dao.DictionaryDao;
import ru.compft.common.data.Dictionary;
import ru.compft.common.utils.CommonUtils;
import ru.compft.common.utils.GlobalConstants;

import java.io.*;
import java.util.LinkedList;
import java.util.List;

/**
 * User: ASUS
 * Date: 30.07.12
 * Time: 23:15
 * <p/>
 * Пример реализации функциональности работы со словарями
 * Нужен для демонстрационной версии
 */
public class ExampleDictionaryDaoImpl implements DictionaryDao {
    private static final Logger logger = LoggerFactory.getLogger(ExampleDictionaryDaoImpl.class);

    private String DICTIONARIES_CSV = "/dictionaries.csv";

    @Override
    public List<Dictionary> getAllDictionaries() {
        return readFromFile();
    }

    @Override
    public List<Dictionary> getDictionaries(int from, int count) {
        return CommonUtils.getPartOfList(from, count, readFromFile());
    }

    @Override
    public int countAllDictionaries() {
        return readFromFile().size();
    }

    @Override
    public Dictionary getDictionaryByCode(String code) {
        final List<Dictionary> dictionaryList = readFromFile();
        for (Dictionary dictionary : dictionaryList) {
            if (dictionary.getCode().equals(code))
                return dictionary;
        }
        return null;
    }

    @Override
    public Dictionary getDictionaryById(Long id) {
        final List<Dictionary> dictionaryList = readFromFile();
        for (Dictionary dictionary : dictionaryList) {
            if (dictionary.getId().equals(id))
                return dictionary;
        }
        return null;
    }

    /**
     * Считываем данные из файла
     *
     * @return
     */
    private List<Dictionary> readFromFile() {
        final List<Dictionary> result = new LinkedList<Dictionary>();
        BufferedReader br = null;

        try {
            final String fullPath = System.getProperty(GlobalConstants.USER_DIR_PROP_NAME) + GlobalConstants.CACHE_DATA + DICTIONARIES_CSV;
            final File resourceFile = new File(fullPath);
            if (!resourceFile.exists())
                throw new FileNotFoundException("File " + fullPath + " not found.");

            br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(resourceFile), GlobalConstants.DEFAULT_ENCODING));

            String strLine;
            boolean firstString = true;

            //Read File Line By Line
            while ((strLine = br.readLine()) != null) {
                // пропускаем первую строку, т.к. там лежат имена колонок
                if (firstString) {
                    firstString = false;
                    continue;
                }

                strLine = strLine.replaceAll(GlobalConstants.DOUBLE_QUOTA, GlobalConstants.EMPTY_STRING);

                final String[] fieldArray = strLine.split(GlobalConstants.DOT_COMMA);
                if (fieldArray.length != 4)
                    throw new Exception("Field array more or less than 4 records");

                final Long id = Long.valueOf(fieldArray[0].trim());
                final Long parentId = StringUtils.hasText(fieldArray[1].trim()) ? Long.valueOf(fieldArray[1].trim()) : null;
                final String code = fieldArray[2].trim();
                final String description = fieldArray[3].trim();

                // создаем словарь
                final Dictionary dictionary = new Dictionary(id, code, description);
                result.add(dictionary);
                // todo ищем родительский словарь
            }
        } catch (IOException e) {
            logger.error("Can't read from file " + DICTIONARIES_CSV, e);
        } catch (Exception e) {
            logger.error("Error while read from file " + DICTIONARIES_CSV, e);
        } finally {
            if (br != null)
                try {
                    br.close();
                } catch (IOException e) {
                    // ignore
                }
        }

        return result;
    }
}
